﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;


namespace P2.Cuberry.Framework.CalendarLibrary
{
	public enum DateMode
	{
		OneDay = 0,
		FiveDay = 1,
		SevenDay = 2,
		Month = 3
	}

	public partial class Calendar : DataGridView
	{
		private DateMode m_dateMode = DateMode.OneDay;
		private DateTime m_startTime = DateTime.Now;
		private List<CalendarItem> m_items = null;
		internal Dictionary<CalendarItem, int> OverlapCount = new Dictionary<CalendarItem, int>();
		internal Dictionary<CalendarItem, int> OrderCount = new Dictionary<CalendarItem, int>();

		public Calendar()
		{
			InitializeComponent();
			m_items = new List<CalendarItem>();
			this.ReadOnly = true;
			this.AllowUserToAddRows = false;
			this.AllowUserToOrderColumns = false;
			this.AllowUserToResizeRows = false;
			this.AllowUserToResizeColumns = false;
			this.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
			InitializeDisplay();
			this.SizeChanged += new EventHandler(Calendar_SizeChanged);
		}

		void Calendar_SizeChanged(object sender, EventArgs e)
		{
			try
			{
				switch (DateMode)
				{
					case DateMode.SevenDay:
						int height = (int)((this.Height - this.Columns[0].HeaderCell.Size.Height - 2) / 3);
						for (int i = 0; i < 3; i++)
							this.Rows[i].Height = height;
						break;
					case DateMode.Month:
						height = (int)((this.Height - this.Columns[0].HeaderCell.Size.Height - 2) / 5);
						for (int i = 0; i < 5; i++)
							this.Rows[i].Height = height;
						break;
					default:
						break;
				}
			}
			catch (Exception ex)
			{
				Trace.WriteLine(ex.ToString());
			}
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			// Calling the base class OnPaint
			base.OnPaint(pe);
		}

		public DateMode DateMode
		{
			get
			{
				return m_dateMode;
			}
			set
			{
				m_dateMode = value;
				InitializeDisplay();
			}
		}

		public DateTime StartTime
		{
			get
			{
				DateTime d = new DateTime(m_startTime.Year, m_startTime.Month, m_startTime.Day);
				if (this.DateMode == DateMode.OneDay || d.DayOfWeek == DayOfWeek.Monday)
					return d;
				else
				{
					// Get the previous Monday
					while (d.DayOfWeek != DayOfWeek.Monday)
						d = d.Subtract(new TimeSpan(1, 0, 0, 0));
					return d;
				}
			}
			set
			{
				if (!m_startTime.Equals(value))
				{
					m_startTime = value;
					InitializeDisplay();
				}
			}
		}

		public DateTime EndTime
		{
			get
			{
				if (this.DateMode == DateMode.OneDay)
					return this.StartTime.AddDays(1);
				else if (this.DateMode == DateMode.FiveDay)
					return this.StartTime.AddDays(5);
				else if (this.DateMode == DateMode.SevenDay)
					return this.StartTime.AddDays(7);
				else
					return this.StartTime.AddDays(35);
			}
		}

		public List<CalendarItem> CalendarItems
		{
			get
			{
				return m_items;
			}
			set
			{
				m_items = value;
			}
		}

		protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
		{
			try
			{
				if (keyData == Keys.Escape)
				{
					this.ClearSelection();
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				Trace.WriteLine(ex.ToString());
				return false;
			}
		}

		public void InitializeDisplay()
		{
			try
			{
				if (this.ColumnCount > 0)
					this.Columns.Clear();

				switch (DateMode)
				{
					case DateMode.OneDay:
						this.RowHeadersVisible = true;
						this.ColumnHeadersVisible = true;
						DayColumn dc = new DayColumn(this.StartTime);
						this.Columns.Add(dc);
						this.RowCount = 48;
						for (int i = 0; i < this.RowCount; i++)
							this.Rows[i].HeaderCell = new HalfHourRowHeaderCell();
						this.RowHeadersWidth = 50;
						this.ColumnHeadersHeight = 18;
						this.FirstDisplayedScrollingRowIndex = 16;
						this.MultiSelect = true;
						break;
					case DateMode.FiveDay:
						this.RowHeadersVisible = true;
						this.ColumnHeadersVisible = true;
						for (int i = 0; i < 5; i++)
						{
							DayColumn d = new DayColumn(this.StartTime.AddDays(i));
							this.Columns.Add(d);
						}
						this.RowCount = 48;
						this.FirstDisplayedScrollingRowIndex = 16;
						for (int i = 0; i < this.RowCount; i++)
							this.Rows[i].HeaderCell = new HalfHourRowHeaderCell();
						this.RowHeadersWidth = 50;
						this.ColumnHeadersHeight = 18;
						this.MultiSelect = true;
						break;
					case DateMode.SevenDay:
						HalfWeekColumn hc1 = new HalfWeekColumn(this.StartTime);
						HalfWeekColumn hc2 = new HalfWeekColumn(this.StartTime.AddDays(3));
						this.Columns.AddRange(hc1, hc2);
						this.RowCount = 3;
						this.RowHeadersVisible = false;
						this.ColumnHeadersVisible = false;
						this.MultiSelect = false;
						int height = (int)((this.Height - this.Columns[0].HeaderCell.Size.Height - 2) / 3);
						for (int i = 0; i < 3; i++)
							this.Rows[i].Height = height;
						break;
					case DateMode.Month:
						this.RowHeadersVisible = false;
						this.ColumnHeadersVisible = true;
						this.RowTemplate = new WeekRow();
						for (int i = 0; i < 6; i++)
						{
							WeekDayColumn c = new WeekDayColumn();
                            c.DisplayIndex = i;
							this.Columns.Add(c);
						}
						this.MultiSelect = false;
						this.RowCount = 5;
						this.ColumnHeadersHeight = 22;
						height = (int)((this.Height - this.Columns[0].HeaderCell.Size.Height - 2) / 5);
						for (int i = 0; i < 5; i++)
							this.Rows[i].Height = height;
						break;
					default:
						break;
				}
				this.ClearSelection();
			}
			catch (Exception ex)
			{
				Trace.WriteLine(ex.ToString());
			}
		}

	}
}
